#include "graphsupport/graph/operation/GenBipartLinkNear.h"

#include <algorithm>

#include "graphsupport/graph/BiGraph.h"

GenBipartLinkNear::GenBipartLinkNear()
{
}

int generateNeighbor( Graph & gr, int vert, IOperationSettings & genSettings )
{
	BiGraph * bigraph = dynamic_cast< BiGraph * >( & gr );

	if ( !bigraph )
	{
		return genSettings.randomInt( gr.getVertexCount() );
	}
	int otherBipart = vert < bigraph->getFirstBipart() ? bigraph->getSecondBipart() : bigraph->getFirstBipart();
	int result = genSettings.randomInt( otherBipart );
	if ( vert < bigraph->getFirstBipart() )
	{
		result += bigraph->getFirstBipart();
	}
	return result;
}

void GenBipartLinkNear::applyTo( Graph & graph, IOperationSettings & genSettings )
{
	int n = graph.getVertexCount();
	Graph::AdjMatrixType adjMatrix = graph.getAdjacentMatrixArr();

	int neighborsBeg = genSettings.neighborsBeg;
	int neighborsRange = genSettings.neighborsRange;

	assert( neighborsRange > 0 );

	for ( int i = 0; i < n; i++ )
	{
		int curNeighbors = neighborsBeg + genSettings.randomInt( neighborsRange );
		for ( int j = 0; j < curNeighbors; j++ )
		{
			int dest = generateNeighbor( graph, i, genSettings );
			adjMatrix[i][dest] = std::min( adjMatrix[i][dest], 1.0 );
		}
	}
}
